﻿using AutoMapper;
using DFGK.IRepository;
using DFGK.IService;
using DFGK_WMS.Model.Dto;
using DFGK_WMS.Model.Models;
using Yitter.IdGenerator;

namespace DFGK.Service
{
    public class ReceivingBillService : BaseService, IReceivingBillService
    {
        private readonly IMaterialRepository _materialRepository;
        private readonly ISupplierRepository _supplierRepository;
        private readonly ICustomerRepository _customerRepository;
        private readonly IWarehouseRepository _warehouseRepository;
        private readonly IReceivingBillRepository _receiptBillRepository;
        private readonly IReceivingBillDetailRepository _receiptDetailRepository;
        private readonly IUnitOfWork _unitOfWork;
        public ReceivingBillService(IMapper mapper, ISupplierRepository _supplierRepository, ICustomerRepository customerRepository, IWarehouseRepository warehouseRepository, IReceivingBillRepository receiptBillRepository, IReceivingBillDetailRepository receiptDetailRepository, IMaterialRepository materialRepository, IUnitOfWork unitOfWork) : base(mapper)
        {
            this._supplierRepository = _supplierRepository;
            _materialRepository = materialRepository;
            _customerRepository = customerRepository;
            _warehouseRepository = warehouseRepository;
            _receiptBillRepository = receiptBillRepository;
            _receiptDetailRepository = receiptDetailRepository;
            _unitOfWork = unitOfWork;
        }

        public bool AddReceivingBill(ReceivingBill m, out string message)
        {
            message = "";
            #region 基础数据判断赋值
            if (m.SupplierId != null)
            {
                var sobj = _supplierRepository.QueryEntityById((long)m.SupplierId);
                if (sobj != null)
                {
                    m.SupplierName = sobj.Name;
                }
                else
                {
                    message = "供应商不存在或者已被禁用！";
                    return false;
                }
            }
            if (m.CustomerId != null)
            {
                var cobj = _customerRepository.QueryEntityById((long)m.CustomerId);
                if (cobj != null)
                {
                    m.CustomerName = cobj.Name;
                }
                else
                {
                    message = "客户不存在或者已被禁用！";
                    return false;
                }
            }
            if (m.WarehouseId != null)
            {
                var wobj = _warehouseRepository.QueryEntityById((long)m.WarehouseId);
                if (wobj != null && wobj.Status == 1)
                {
                    m.WarehouseCode = wobj.Code;
                    m.WarehouseName = wobj.Name;
                }
                else
                {
                    message = "库房不存在或者已被禁用！";
                    return false;
                }
            }
            m.Status = 0;
            m.ReceivedQTY = 0;
            #endregion
            _unitOfWork.BeginTransaction();
            try
            {
                foreach (var item in m.BillDetailList)
                {
                    m.TotalQty = item.Qty;
                    _receiptBillRepository.AddEntity(m);
                    _unitOfWork.SaveChangesEntity();
                    var mobj = _materialRepository.QueryEntityById(item.MaterialId);
                    if (mobj == null)
                    {
                        message = "物料信息有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (item.Qty <= 0)
                    {
                        message = "收货数量不能小于0";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (item.Qty % 1 != 0)
                    {
                        message = "收货数量包含小数";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    item.Id = YitIdHelper.NextId();
                    item.MaterialName = mobj.Name;
                    item.MaterialCode = mobj.Code;
                    item.MaterialTypeName = mobj.MaterialCategoryName;
                    item.SupplierId = m.SupplierId;
                    item.SupplierName = m.SupplierName;
                    if (mobj.ExpirationMonth != null)
                        item.ExpireDate = DateTime.Now.AddMonths((int)mobj.ExpirationMonth);
                    //关联单号
                    item.BillNo = m.BillNo;
                    item.BillId = m.Id;
                    //初始化状态
                    item.Status = 0;
                    _receiptDetailRepository.AddEntity(item);
                }
                if (_unitOfWork.SaveChangesEntity())
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        public bool DelReceivingBill(long rid, out string message)
        {
            message = "";
            var robj = _receiptBillRepository.QueryEntityById(rid);
            if (robj != null)
            {
                if (robj.Status == 1 || robj.Status == 2 || robj.Status == 3)
                {
                    message = "作业中和已完成的单据不能再删除";
                    return false;
                }
                _receiptBillRepository.DelEntity(robj);
                var rodobj = _receiptDetailRepository.QueryEntityWhere(x => x.BillId == robj.Id);
                if (rodobj != null)
                    _receiptDetailRepository.DelEntity(rodobj);
                return _unitOfWork.SaveChangesEntity();
            }
            message = "找不到收货单!";
            return false;
        }

        public ReceivingBill? GetReceivingBillById(long rid)
        {
            var robj = _receiptBillRepository.QueryEntityById(rid);
            if (robj == null)
                return null;
            ReceivingBill? robjs = new ReceivingBill();
            robjs = robj;
            var rdobj = _receiptDetailRepository.QueryIsEntityWhere(x => x.BillId == robj.Id);
            if (rdobj != null)
            {
                robjs.BillDetailList.Add(rdobj);
            }
            return robj;
        }

        public List<ReceivingBillListDto> GetReceivingBillList(string? ordersn,int? billtype, string? materialkey, int status, int pageIndex, int pageSize, out int totalCount)
        {
            var rlist = _receiptBillRepository.GetEntityAlls();
            var rdlist = _receiptDetailRepository.GetEntityAlls();
            rlist = rlist.Where(x => x.BillType == billtype);
            if (!string.IsNullOrEmpty(ordersn))
                rlist = rlist.Where(x => x.BillNo.Contains(ordersn));

            if (status < 4)
                rlist = rlist.Where(x => x.Status == status);
            if (status == 5)
                rlist = rlist.Where(x => x.Status < 2);
            if (!string.IsNullOrEmpty(materialkey))
                rdlist = rdlist.Where(x => x.MaterialCode.Contains(materialkey) || x.MaterialName.Contains(materialkey));

            var list = from a in rlist
                       join b in rdlist
                       on a.Id equals b.BillId
                       select new ReceivingBillListDto
                       {
                           Id = a.Id,
                           BillNo = a.BillNo,
                           SupplierId = a.SupplierId,
                           SupplierName = a.SupplierName,
                           Status = GetStatus(a.Status),
                           BeginDate = a.BeginDate,
                           EndDate = a.EndDate,
                           CreateDate = a.CreateDate,
                           TotalQty = a.TotalQty,
                           ReceivedQTY = b.ReceivedQty,
                           MaterialCode = b.MaterialCode,
                           MaterialName = b.MaterialName,
                           BatchNo = b.BatchNo,
                           AduitStatus=a.AduitStatus
                       };
            totalCount = list.Count();
            var query = list.OrderByDescending(x => x.CreateDate).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            return query.ToList();
        }

        private static string GetStatus(int status)
        {
            switch (status)
            {
                case 0:
                    return "未开始";
                case 1:
                    return "未完成";
                case 2:
                    return "已完成";
            }
            return "";
        }

        public bool UpdReceivingBill(ReceivingBill m, out string message)
        {
            message = "";
            #region 基础数据判断赋值
            if (m.Status != 0)
            {
                message = "收货中和已完成单据不可修改！";
                return false;
            }
            if (m.SupplierId != null)
            {
                var sobj = _supplierRepository.QueryEntityById((long)m.SupplierId);
                if (sobj != null)
                {
                    m.SupplierName = sobj.Name;
                }
                else
                {
                    message = "供应商不存在或者已被禁用！";
                    return false;
                }
            }
            if (m.CustomerId != null)
            {
                var cobj = _customerRepository.QueryEntityById((long)m.CustomerId);
                if (cobj != null)
                {
                    m.CustomerName = cobj.Name;
                }
                else
                {
                    message = "客户不存在或者已被禁用！";
                    return false;
                }
            }
            if (m.WarehouseId != null)
            {
                var wobj = _warehouseRepository.QueryEntityById((long)m.WarehouseId);
                if (wobj != null && wobj.Status == 1)
                {
                    m.WarehouseCode = wobj.Code;
                    m.WarehouseName = wobj.Name;
                }
                else
                {
                    message = "库房不存在或者已被禁用！";
                    return false;
                }
            }
            #endregion
            _unitOfWork.BeginTransaction();
            try
            {
                var rdlist = _receiptDetailRepository.GetEntityWhereAll(x => x.BillId == m.Id);
                if (rdlist.Any())
                    _receiptDetailRepository.DelEntityList(rdlist.ToList());
                foreach (var item in m.BillDetailList)
                {
                    m.TotalQty = item.Qty;
                    _receiptBillRepository.UpdEntity(m);
                    var mobj = _materialRepository.QueryEntityById(item.MaterialId);
                    if (mobj == null)
                    {
                        message = "物料信息有误！";
                        return false;
                    }
                    if (item.Qty <= 0)
                    {
                        message = "收货数量不能小于0";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (item.Qty % 1 != 0)
                    {
                        message = "收货数量包含小数";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    item.Id = YitIdHelper.NextId();
                    item.MaterialName = mobj.Name;
                    item.MaterialCode = mobj.Code;
                    item.MaterialTypeName = mobj.MaterialCategoryName;
                    item.SupplierId = m.SupplierId;
                    item.SupplierName = m.SupplierName;
                    //关联单号
                    item.BillNo = m.BillNo;
                    item.BillId = m.Id;
                    _receiptDetailRepository.AddEntity(item);
                }
                if (_unitOfWork.SaveChangesEntity())
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }

        public ReceivingBillListDto? GetReceivingBillByMaerialCode(string code)
        {
            var rlist = _receiptBillRepository.GetEntityWhereAll(x => x.Status < 2);
            var rdlist = _receiptDetailRepository.GetEntityWhereAll(x => x.MaterialCode == code);

            var list = from a in rlist
                       join b in rdlist
                       on a.Id equals b.BillId
                       select new ReceivingBillListDto
                       {
                           Id = a.Id,
                           BillNo = a.BillNo,
                           SupplierId = a.SupplierId,
                           SupplierName = a.SupplierName,
                           Status = GetStatus(a.Status),
                           BeginDate = a.BeginDate,
                           EndDate = a.EndDate,
                           CreateDate = a.CreateDate,
                           TotalQty = a.TotalQty,
                           ReceivedQTY = b.ReceivedQty,
                           MaterialCode = b.MaterialCode,
                           MaterialName = b.MaterialName,
                           BatchNo = b.BatchNo,
                       };
            if (list.Any())
                return list.FirstOrDefault();
            return null;
        }

        public bool EBSAddReceivingBill(EBSReceivingBillDTO eBSReceivingBillList, out string message)
        {
            message = string.Empty;
            ReceivingBill receivingBill = new();
            receivingBill.BillNo = eBSReceivingBillList.BilNo;
            receivingBill.Status = 0;
            receivingBill.IsDel = false;
            receivingBill.CreateDate = DateTime.Now;
            receivingBill.EndDate = DateTime.Now;
            receivingBill.CreateUserId = 0;
            receivingBill.ModifyUserId = 0;
            receivingBill.BillType = eBSReceivingBillList.BillType;

            var warehous = _warehouseRepository.QueryEntityWhere(w=>w.Code == "X01");
            if (warehous != null)
            {
                receivingBill.WarehouseCode = warehous.Code;
                receivingBill.WarehouseId = warehous.Id;
                receivingBill.WarehouseName = warehous.Name;
            }

            _unitOfWork.BeginTransaction();
            try
            {
                foreach (var item in eBSReceivingBillList.items)
                {
                    receivingBill.TotalQty = item.Qty;
                    _receiptBillRepository.AddEntity(receivingBill);
                    _unitOfWork.SaveChangesEntity();
                    var mobj = _materialRepository.QueryEntityWhere(r => r.Code == item.MaterialCode);
                    if (mobj == null)
                    {
                        message = "物料信息有误！";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (item.Qty <= 0)
                    {
                        message = "收货数量不能小于0";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    if (item.Qty % 1 != 0)
                    {
                        message = "收货数量包含小数";
                        _unitOfWork.RollbackChanges();
                        return false;
                    }
                    ReceivingBillDetail receivingBillDetail = new();
                    receivingBillDetail.Id = YitIdHelper.NextId();
                    receivingBillDetail.MaterialName = mobj.Name;
                    receivingBillDetail.MaterialCode = mobj.Code;
                    receivingBillDetail.Qty = item.Qty;
                    receivingBillDetail.MaterialId = mobj.Id;
                    receivingBillDetail.MaterialTypeName = mobj.MaterialCategoryName;
                    receivingBillDetail.SupplierId = receivingBill.SupplierId;
                    receivingBillDetail.SupplierName = receivingBill.SupplierName;
                    receivingBillDetail.ReceivedQty = 0;
                    receivingBillDetail.CreateDate = DateTime.Now;

                    //关联单号
                    receivingBillDetail.BillNo = receivingBill.BillNo;
                    receivingBillDetail.BillId = receivingBill.Id;
                    //初始化状态
                    receivingBillDetail.Status = 0;
                    _receiptDetailRepository.AddEntity(receivingBillDetail);
                }
                if (_unitOfWork.SaveChangesEntity())
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                message = "添加单据失败!";
                return false;
            }
            catch (Exception)
            {
                _unitOfWork.RollbackChanges();
                throw;
            }
        }
    }
}
